<template>
  <div class="ct-tooltip" v-on="outEvents">
    <!-- 触发元素 -->

    <div class="ct-tooltip__trigger" ref="triggerRef" v-on="events"><slot></slot></div>
    <!-- 提示元素 -->
    <div class="ct-tooltip__popper" v-show="isOpen" ref="popperRef">
      <slot name="content">{{ content }}</slot>
      <!-- 小箭头 -->
      <div id="arrow" data-popper-arrow></div>
    </div>
  </div>
</template>
<script setup>
import { ref, watch, reactive, computed } from 'vue'
import { createPopper } from '@popperjs/core'
import propsOptions from './props'
import { debounce } from 'lodash-es'
defineOptions({
  name: 'CTTooltip',
})
const emit = defineEmits(['visible-change'])
const props = defineProps(propsOptions)

const triggerRef = ref(null)
const popperRef = ref(null)
let isOpen = ref(false)

let events = reactive({})
let outEvents = reactive({})

const openDebounce = debounce(() => {
  isOpen.value = true
  emit('visible-change', isOpen.value)
}, props.openDelay)
const closeDebounce = debounce(() => {
  isOpen.value = false
  emit('visible-change', isOpen.value)
}, props.closeDelay)

const open = () => {
  closeDebounce.cancel()
  openDebounce()
}

const close = () => {
  openDebounce.cancel()
  closeDebounce()
}

let popperInstance = null

const popperOffset = computed(() => ({
  placement: props.placement,
  modifiers: {
    name: 'offset',
    options: {
      offset: [0, 6],
    },
  },
}))

watch(
  isOpen,
  (val) => {
    if (val) {
      if (triggerRef.value && popperRef.value) {
        popperInstance = createPopper(triggerRef.value, popperRef.value, popperOffset.value)
      } else {
        popperInstance?.destroy()
      }
    }
  },
  { flush: 'post' },
)

const attachEvents = () => {
  if (props.trigger === 'hover') {
    events['mouseenter'] = open
    outEvents['mouseleave'] = close
  } else {
    events['click'] = () => {
      isOpen.value ? close() : open()
    }
  }
}

if (!props.manual) {
  attachEvents()
}

defineExpose({
  open,
  close,
})
</script>
<style lang="scss" scoped></style>
